//  Copyright 201 David Ekholm, jAlbum AB
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.package net.jalbum.editor;

package demo;

import java.io.File;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import net.jalbum.injector.ArgsInjector;
import net.jalbum.injector.Argument;
import net.jalbum.injector.InjectorException;
import net.jalbum.injector.Program;
import net.jalbum.injector.Switch;

/**
 * Example application utilizing ArgsInjector framework to parse and inject command line parameters
 * This example will print a list of files sorted according to the user's specification 
 * @author david
 */
@Program(command="java -jar FileSorter.jar", description="Print a list of files sorted according to the user's specification", example="-date -top 10 -r folder1 folder2 folder3")
public class FileSorter {

    @Switch(name = "date", description = "Order files by last modified date", disallow = "size")
    boolean orderByDate;
    @Switch(name = "size", description = "Order files by file size", disallow = "date")
    boolean orderBySize;
    @Switch(alias = 'r', description = "Step into folders and sort their content too")
    boolean recursive;
    @Switch(description = "Print the n top resulting files")
    Integer top;
    @Argument(mandatory = true, description = "List of files and folders to sort")
    String[] files;
    private List<File> fileList = new ArrayList<File>();

    public void processDir(File dir) {
        if (dir.isDirectory()) {
            for (File f : dir.listFiles()) {
                fileList.add(f);
                if (f.isDirectory() && recursive) {
                    processDir(f);
                }
            }
        }
    }

    public void sort() {
        for (String name : files) {
            File f = new File(name);
            fileList.add(f);
            if (f.isDirectory()) {
                processDir(f);
            }
        }

        // Now sort on either date, size or name
        File[] allFiles = fileList.toArray(new File[0]);
        Comparator<File> comp;
        if (orderByDate) {
            comp = new Comparator<File>() {

                @Override
                public int compare(File f1, File f2) {
                    return (int) (f1.lastModified() - f2.lastModified());
                }
            };
        } else if (orderBySize) {
            comp = new Comparator<File>() {

                @Override
                public int compare(File f1, File f2) {
                    return (int) (f1.length() - f2.length());
                }
            };

        } else {
            comp = new Comparator<File>() {

                @Override
                public int compare(File f1, File f2) {
                    return (int) (f1.getName().compareTo(f2.getName()));
                }
            };
        }

        Arrays.sort(allFiles, comp);
        if (top == null) {
            top = allFiles.length;
        }
        else {
            top = Math.min(allFiles.length, top);
        }
        DateFormat df = DateFormat.getDateTimeInstance();
        for (int i=0; i<top; i++) {
            File f = allFiles[i];
            System.out.println(f.length() + "\t" + df.format(new Date(f.lastModified())) + "\t" + f.getName());
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            FileSorter fs = new FileSorter();
            ArgsInjector injector = new ArgsInjector(args, fs);
            fs.sort();

        }
        catch (InjectorException ex) {
            System.out.println(ex.getMessage());
        }
    }
}
